package com.lsh.oms.worker.service.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dangdang.ddframe.job.api.JobExecutionMultipleShardingContext;
import com.dangdang.ddframe.job.plugin.job.type.simple.AbstractSimpleElasticJob;
import com.lsh.oms.core.dao.order.OrderDetailDao;
import com.lsh.oms.core.dao.order.OrderHeadDao;
import com.lsh.oms.core.enums.TaskStatus;
import com.lsh.oms.core.enums.TaskType;
import com.lsh.oms.core.model.order.OrderDetail;
import com.lsh.oms.core.model.order.OrderHead;
import com.lsh.oms.core.model.po.OmsTask;
import com.lsh.oms.core.proxy.handler.OrderConcurrentHandler;
import com.lsh.oms.core.proxy.model.GoodsBaseSaleInfo;
import com.lsh.oms.core.proxy.model.GoodsServiceChargeItem;
import com.lsh.oms.core.proxy.service.WgServiceProxy;
import com.lsh.oms.core.service.order.OrderQueryService;
import com.lsh.oms.core.service.po.OmsTaskService;
import com.lsh.oms.core.utils.model.Good;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * Project Name: FillOrderDetailTask
 * 北京链商电子商务有限公司
 * Auth: wangliutao
 * Date: 19/4/18
 * Package Name: com.lsh.oms.worker.service.task
 * Description:
 */
@Component
@Deprecated
public class FillOrderDetailTask extends AbstractSimpleElasticJob {
    private static final Logger logger = LoggerFactory.getLogger(FillOrderDetailTask.class);

    @Autowired
    private OrderQueryService orderQueryService;

    @Autowired
    private WgServiceProxy wgServiceProxy;

    @Autowired
    private OrderHeadDao orderHeadDao;

    @Autowired
    private OrderDetailDao orderDetailDao;

    @Autowired
    private OmsTaskService omsTaskService;

    @Value("${mis.host}")
    private String misUrl;

    @Value("${shopUrl}")
    private String shopUrl;

    protected boolean process(OmsTask omsTask, Map<Integer, Integer> zoneGroupIdMap) {
        if (omsTask == null) {
            return false;
        }

        Long orderCode = Long.valueOf(omsTask.getRefCode());
        String logSign = "【" + orderCode + " - 填充订单详情税率】";
        try {
            if (!OrderConcurrentHandler.lockOrder(orderCode)) {
                logger.info("{}processData({}) interrupt... 订单正在处理...", logSign, orderCode);
                return false;
            }

            OrderHead orderHead = orderQueryService.findByCode(Long.valueOf(orderCode), false, true);
            if (orderHead == null || CollectionUtils.isEmpty(orderHead.getDetails())) {
                logger.info("{}查询不到订单 或 订单详情，订单号：{}", logSign, orderCode);
                return false;
            }

            JSONObject orderExt = JSON.parseObject(orderHead.getExt());
            String orderDc = orderExt.getString("orderDc");
            String providerId = orderExt.getString("providerId");
            if (!"LSx01".equals(orderDc) || StringUtils.isEmpty(providerId)) {
                logger.info("{}该订单不是云仓订单，订单号：{}", logSign, orderCode);
                return false;
            }

            Integer groupId = zoneGroupIdMap.get(orderHead.getRegionCode());
            if (groupId == null) {
                logger.info("{}该订单查不到默认用户组，订单号：{}", logSign, orderCode);
                return false;
            }

            Set<Long> skuCodes = new HashSet<>();
            Set<Long> goodsCodes = new HashSet<>();
            for (OrderDetail detail : orderHead.getDetails()) {
                skuCodes.add(detail.getSkuCode());
                goodsCodes.add(detail.getGoodsCode());
            }

            Map<Long, List<GoodsBaseSaleInfo>> skuGoodsInfoMap = new HashMap<>();
//                    GoodsServiceUtils.getGoodsBaseSaleInfo(skuCodes, groupId, misUrl, logSign, orderHead.getVenderId());
            if (skuGoodsInfoMap == null || skuGoodsInfoMap.isEmpty()) {
                logger.info("{}从商城查询商品信息为空，订单号：{}", logSign, orderCode);
                return false;
            }

            Set<String> supplyCodes = new HashSet<>();
            Map<Long, BigDecimal> skuCodePriceMap = new HashMap<>();
            Map<String, Long> supplySkuCodeMap = new HashMap<>();
            for (Map.Entry<Long, List<GoodsBaseSaleInfo>> entry : skuGoodsInfoMap.entrySet()) {
                Long skuCode = entry.getKey();

                BigDecimal eaSalePrice = null;
                int count = 0;
                for (GoodsBaseSaleInfo baseSaleInfo : entry.getValue()) {
                    // isYun = 1 表示是云仓商品
                    if (Integer.valueOf(1).equals(baseSaleInfo.getIsYun())) {
                        BigDecimal salePrice = baseSaleInfo.getSalePrice();
                        BigDecimal saleUnit = baseSaleInfo.getSaleUnit();

                        // 过滤，与订单供商不同的信息
                        if (!providerId.equals(String.valueOf(baseSaleInfo.getProviderId()))) {
                            continue;
                        }

                        if (saleUnit == null || saleUnit.compareTo(BigDecimal.ZERO) <= 0 || salePrice == null) {
                            continue;
                        }

                        BigDecimal averageSalePrice = salePrice.divide(saleUnit, 6, BigDecimal.ROUND_HALF_DOWN);
                        if (eaSalePrice == null) {
                            eaSalePrice = averageSalePrice;
//                            String supplyCode = baseSaleInfo.getSupplySkuCode();
//                            supplySkuCodeMap.put(supplyCode, skuCode);
//                            supplyCodes.add(supplyCode);
                            count += 1;
                        } else {
                            if (averageSalePrice.compareTo(BigDecimal.ZERO) > 0) {
                                eaSalePrice = eaSalePrice.add(averageSalePrice);
                                count += 1;
                            }
                        }
                    }
                }

                if (eaSalePrice != null && count > 0) {
                    skuCodePriceMap.put(skuCode, eaSalePrice.divide(BigDecimal.valueOf(count), 6, BigDecimal.ROUND_HALF_DOWN));
                }
            }

            // TODO: 从商品服务，查询supplySkuCode; 此处org、market、dc均写死；2-0-LSx01
            Map<Long, Good> goodsMap = new HashMap<>();
//                    GoodsServiceUtils.getGoodsInfoMapByGoodsCodes(shopUrl, goodsCodes, 0, SupplierOrg.LSH.getValue(), "LSx01", orderHead.getVenderId());
            logger.info("{} 查询商品服务，返回：{}", logSign, JSON.toJSONString(goodsMap));
            for (Map.Entry<Long, Good> entry : goodsMap.entrySet()) {
                Good goods = entry.getValue();
                supplyCodes.add(goods.getSupplySkuCode());
                supplySkuCodeMap.put(goods.getSupplySkuCode(), goods.getSkuCode());
            }

            if (CollectionUtils.isEmpty(supplyCodes)) {
                logger.info("{}supplyCodes为空，订单号：{}", logSign, orderCode);
                return false;
            }

            // 调进销存查询税率等信息
            // TODO: owner_id为云仓供商
            List<GoodsServiceChargeItem> goodsServiceChargeItemList = wgServiceProxy.getGoodsServiceCharge(supplyCodes, providerId, orderHead.getVenderId());
            if (CollectionUtils.isEmpty(goodsServiceChargeItemList)) {
                logger.info("{}PSI查询商品税率信息为空，订单号：{}", logSign, orderCode);
                return false;
            }

            String psiProviderId = null;
            Map<Long, GoodsServiceChargeItem> skuCodeChargeMap = new HashMap<>();
            for (GoodsServiceChargeItem item : goodsServiceChargeItemList) {
                Long skuCode = supplySkuCodeMap.get(item.getSkuSupplyCode());
                if (skuCode != null) {
                    skuCodeChargeMap.put(skuCode, item);
                    psiProviderId = item.getVenderId();
                }
            }

            if (StringUtils.isEmpty(psiProviderId)) {
                logger.info("{}PSI查询供商信息为空，订单号：{}", logSign, orderCode);
                return false;
            }

            // todo:填写EA的价格
            for (OrderDetail orderDetail : orderHead.getDetails()) {
                GoodsServiceChargeItem chargeItem = skuCodeChargeMap.get(orderDetail.getSkuCode());
                BigDecimal salePrice = skuCodePriceMap.get(orderDetail.getSkuCode());
                BigDecimal saleUnit = orderDetail.getGoodsSaleUnit();

                if (chargeItem == null || salePrice == null) {
                    logger.info("{} 查不到税率信息、销售价，链商码：{}", logSign, orderDetail.getSkuCode());
                    return false;
                }

                // mis展示为，单价 * 售卖单位 的价格
                BigDecimal baseSalePrice = salePrice.multiply(saleUnit).setScale(6, BigDecimal.ROUND_HALF_DOWN);
                BigDecimal deductRate = chargeItem.getServiceCharge().divide(BigDecimal.valueOf(100)); // 服务费率
                BigDecimal taxRate = BigDecimal.valueOf(chargeItem.getTax()).divide(BigDecimal.valueOf(100)); // 税率
                JSONObject ext = JSON.parseObject(orderDetail.getDetailExt());
                if (baseSalePrice.compareTo(BigDecimal.ZERO) <= 0) {
                    ext.put("baseSalePrice", baseSalePrice.setScale(2, BigDecimal.ROUND_HALF_DOWN)); // 基础售价
                    ext.put("deductRate", deductRate); // 扣点
                    ext.put("taxRate", taxRate); // 税率
                    ext.put("taxCost", 0.00); // 税额
                    ext.put("excludeTaxCost", 0.001); // 未税采购价
                    ext.put("includeTaxCost", 0.001); // 含税采购价
                } else {
                    // 含税采购价 = （1 - 扣点）* 售价
                    BigDecimal includeTaxCost = (BigDecimal.ONE.subtract(deductRate)).multiply(baseSalePrice).setScale(6, BigDecimal.ROUND_HALF_DOWN);
                    // 未税采购价 = （（1 - 扣点）* 售价）/ （1 + 税率）
                    BigDecimal excludeTaxCost = includeTaxCost.divide(BigDecimal.ONE.add(taxRate), 6, BigDecimal.ROUND_HALF_DOWN);
                    // 税额 = 售价 * 税率
                    BigDecimal taxCost = includeTaxCost.subtract(excludeTaxCost).setScale(2, BigDecimal.ROUND_HALF_DOWN);

                    ext.put("baseSalePrice", baseSalePrice.setScale(2, BigDecimal.ROUND_HALF_DOWN)); // 基础售价
                    ext.put("deductRate", deductRate); // 扣点
                    ext.put("taxRate", taxRate); // 税率
                    ext.put("taxCost", taxCost); // 税额
                    ext.put("excludeTaxCost", excludeTaxCost.setScale(2, BigDecimal.ROUND_HALF_DOWN)); // 未税采购价
                    ext.put("includeTaxCost", includeTaxCost.setScale(2, BigDecimal.ROUND_HALF_DOWN)); // 含税采购价
                }

                OrderDetail update = new OrderDetail();
                update.setId(orderDetail.getId());
                update.setDetailExt(ext.toJSONString());
                this.orderDetailDao.update(update);
            }

            orderExt.put("psiProviderId", psiProviderId);
            OrderHead oh4Update = new OrderHead();
            oh4Update.setId(orderHead.getId());
            oh4Update.setExt(orderExt.toJSONString());
            this.orderHeadDao.update(oh4Update);

            return true;
        } catch (Exception e) {
            logger.error(logSign + "任务处理异常", e);
        } finally {
            OrderConcurrentHandler.unlockOrder(orderCode);
        }

        return false;
    }

    @Override
    public void process(JobExecutionMultipleShardingContext context) {
        Map<Integer, Integer> map = this.getZoneGroupIdConfig(context);
        if (map == null || map.isEmpty()) {
            logger.info("【填充订单详情税率】任务参数为空!");
            return;
        }

        List<OmsTask> omsTaskList = this.omsTaskService.getTasksByTypeAndStatuses(this.getTaskType().getCode(), this.dealTaskStatus(), this.getFetchSize());
        logger.info("【填充订单详情税率】任务size:【{}】", omsTaskList.size());

        for (OmsTask omsTask : omsTaskList) {
            try {
                boolean processFlag = this.process(omsTask, map);

                //更新数据库
                OmsTask task4Update = new OmsTask();
                task4Update.setId(omsTask.getId());
                task4Update.setExecCount(omsTask.getExecCount() + 1);
                Integer taskStatus = TaskStatus.TASK_DEAL_SUCCESS.getCode();
                if (!processFlag) {
                    taskStatus = TaskStatus.TASK_DEAL_FAIL.getCode();
                }
                task4Update.setTaskStatus(taskStatus);
                this.omsTaskService.update(task4Update);
            } catch (Exception e) {
                logger.error("【填充订单详情税率】系统异常", e);
            }
        }

    }

    /**
     * 从elastic-job中，解析"区域-默认用户组"的关系
     *
     * @param context
     * @return
     */
    private Map<Integer, Integer> getZoneGroupIdConfig(JobExecutionMultipleShardingContext context) {
        Map<Integer, String> items = context.getShardingItemParameters();

        String params = items.values().iterator().next();
        Map<Integer, Integer> map = new HashMap<>();
        if (!StringUtils.isEmpty(params)) {
            String[] splits = params.split(";");
            if (splits != null && splits.length > 0) {
                for (String split : splits) {
                    String[] zoneGroupIdArr = split.split("-");
                    if (zoneGroupIdArr == null || zoneGroupIdArr.length != 2) {
                        logger.info("【填充订单详情税率】任务参数不对!");
                        continue;
                    }

                    String zoneCode = zoneGroupIdArr[0];
                    String defaultGroupId = zoneGroupIdArr[1];
                    map.put(Integer.valueOf(zoneCode), Integer.valueOf(defaultGroupId));

                }
            }
        }
        return map;
    }

    private Integer getFetchSize() {
        return 100;
    }

    private TaskType getTaskType() {
        return TaskType.ORDER_DETAIL_RATE;
    }

    private List<Integer> dealTaskStatus() {
        return Arrays.asList(TaskStatus.TASK_UN_DEAL.getCode(), TaskStatus.TASK_DEAL_FAIL.getCode());
    }
}
